(function(angular) {
	'use strict';
	angular.module("fs.waf").factory("facilityService", facilityService);
	facilityService.$inject = [ '$q', 'loggerFactory', 'storageService','categoryService', 'ajaxServiceFactory', 'gridService','modalService', '$filter'];
	function facilityService($q, loggerFactory, storageService, categoryService, ajaxServiceFactory, gridService, modalService, $filter) {
		var log = loggerFactory.getLogger("facilityService");
		var ajaxService = ajaxServiceFactory.buildAjaxService({
			getLimitNodeId : {
				url : 'do/cda/dataList/selectLimitNode',
				method : 'get'
			},
			getDataStatus : {
				url : 'do/cda/dataList/dataStatus',
				method : 'get'
			},
			getCurrencyOptions : {
				url : 'do/cda/dataList/currencies',
				method : 'get'
			}
		});
		
		function getCurrencyOptions() {
			var defer = $q.defer();
			ajaxService.getCurrencyOptions().then(function (response){
				defer.resolve(response);				
			});
			return defer.promise;
		}
		function getDataStatus() {
			var defer = $q.defer();
			ajaxService.getDataStatus().then(function(response) {
				defer.resolve(response ? response.data : {});
			});
			return defer.promise;
		};
		function getLimitNodeIdList() {
			var defer = $q.defer();
			ajaxService.getLimitNodeId().then(function(response) {
				defer.resolve(response);
			});
			return defer.promise;
		}
		
		function initOptionForSearch(ctrl){
			var defer1 = $q.defer();
			var defer2 = $q.defer();
			ajaxService.getDataStatus().then(function(response) {
				defer1.resolve(response ? response.data : {});
			}, angular.noop);
			ajaxService.getCurrencyOptions().then(function(response) {
				defer2.resolve(response ? response.data : {});
			}, angular.noop);
			return $q.all({
				dataStatusOptions : defer1.promise,
				ccyOptions : defer2.promise
			});
		};
		
		function initTree($scope, ctrl){
			ctrl.limitData = [];
			ctrl.facility = {};
			categoryService.getCategoryTree().then(function(response){
				ctrl.limitData = response.data || [];
			});
			getLimitNodeIdList().then( function(response) {
				ctrl.facilityDetailList = response.data ||[];
			});
			ajaxService.getDataStatus().then(function(response) {
				ctrl.dataStatusOptions = response;
			}, angular.noop);
			ajaxService.getCurrencyOptions().then(function(response) {
				ctrl.ccyOptions = response;
				ctrl.ccyOptions.hasEmptyOption = true;
			}, angular.noop);
			
			
			ctrl.limitTreeApi = {};
			ctrl.limitSelected = function(facility) {
				var siteInfo = storageService.getSiteInfo();
				ctrl.facility.limitNodeIds = ctrl.facility.limitNodeIds || [];
				ctrl.facility.limitCatIds = ctrl.facility.limitCatIds || [];
				ctrl.facility.limitNodePaths = ctrl.facility.limitNodePaths || [];
				ctrl.facility.limitNodePathList = angular.isArray(ctrl.facility.limitNodePaths) ? 
						angular.copy(ctrl.facility.limitNodePaths): angular.copy(ctrl.facility.limitNodePaths.split('\n'));
				ctrl.facility.facilityAttrList;
				ctrl.facility.facilityAttrs = [];
				if ( ctrl.facility.limitNodePaths.length == 0) {
					if (facility.type == 'ROOT' || facility.type == 'CATEGORY') {
						ctrl.facility.limitCcy = null;
					} else if ( facility.attr != null && facility.attr.isTxnAllowed == 'N'){
						modalService.openErrorDialogs({
							'messages' :  [ 'js.rms.facility.alert.txnIsNotAllowed']
						});
					} else {
						ctrl.facility.limitCcy = siteInfo.baseCcy;
						ctrl.facility.limitNodeIds.push($filter('encode')(facility.id));
						ctrl.facility.limitCatIds.push(facility.limitCatId);
						ctrl.facility.limitNodePathList.push(facility.nodePath);
						ctrl.facility.limitNodePaths = ctrl.facility.limitNodePathList.join('\n');
						compareNodePath(ctrl, facility);
					}
				} else {																					
					if (facility.type == 'NODE') {
						if ( facility.attr != null && facility.attr.isTxnAllowed == 'N'){
							modalService.openErrorDialogs({
								'messages' :  [ 'js.rms.facility.alert.txnIsNotAllowed']
							});
						} else {
							//old & new selected
//							var facilityId = $filter('encode')(facility.id);
							var facilityLimitCatId = facility.limitCatId;
							if ( ctrl.facility.limitCatIds.indexOf(facilityLimitCatId) != -1){		
								//1.delete same limitCat attrs first
								ctrl.facility.facilityAttrs = angular.copy(ctrl.facility.facilityAttrList) ||[]; 
								for (var i=ctrl.facility.facilityAttrList.length-1;i>=0;i--){
									if ( ctrl.facility.facilityAttrList[i].limitCatId == facilityLimitCatId){
										ctrl.facility.facilityAttrList.splice(ctrl.facility.facilityAttrList.indexOf(ctrl.facility.facilityAttrList[i]), 1);
									}
								}
								//2.
								if (ctrl.facility.limitNodePathList.indexOf(facility.nodePath) != -1) {
									ctrl.facility.limitNodePathList = angular.isArray(ctrl.facility.limitNodePaths) ? 
											angular.copy(ctrl.facility.limitNodePaths): angular.copy(ctrl.facility.limitNodePaths.split('\n'));
											var idIndex = ctrl.facility.limitNodeIds.indexOf($filter('encode')(facility.id));
											var catIdIndex = ctrl.facility.limitCatIds.indexOf(facility.limitCatId);
											var nodePathIndex = ctrl.facility.limitNodePathList.indexOf(facility.nodePath);
											ctrl.facility.limitNodeIds.splice(idIndex , 1);
											ctrl.facility.limitCatIds.splice(catIdIndex , 1);
											ctrl.facility.limitNodePathList.splice(nodePathIndex , 1);
											ctrl.facility.limitNodePaths = ctrl.facility.limitNodePathList.join('\n');
											ctrl.facility.facilityAttrList = angular.copy(ctrl.facility.facilityAttrs) ||[];
											deleteWhenDoubleClick(ctrl, facility);
								} else {
									//compare nodePath, show finally nodePath in list
									angular.forEach( ctrl.facility.limitNodePathList, function (existPath, key){
										var existPathList = existPath.split("/");
										var currentPathList = facility.nodePath.split("/"); 
										var existLen = existPathList.length-1 ;
										var currentLen = currentPathList.length-1 ;
										
										if (existPathList[0] != currentPathList[0] ){
										} else {
											if ( existLen < currentLen){				//old:111/RISK_OWNER, new:111/RISK_OWNER/2
												if ( existPathList[existLen] == currentPathList[existLen]) {
													ctrl.facility.limitNodePathList.splice(ctrl.facility.limitNodePathList.indexOf(existPath), 1);
													ctrl.facility.limitNodePathList.push(facility.nodePath);
												} else {
													ctrl.facility.limitNodePathList.push(facility.nodePath);
												}
											} else if ( existLen > currentLen) {		//old:111/RISK_OWNER/2, new:111/RISK_OWNER
												if ( existPathList[currentLen] == currentPathList[currentLen]) {
													ctrl.facility.limitNodePathList.splice(ctrl.facility.limitNodePathList.indexOf(existLen), 1);
													ctrl.facility.limitNodePathList.push(facility.nodePath);
												} else {
													ctrl.facility.limitNodePathList.push(facility.nodePath);
												}
											} else {	//same nodePath.split().len,     old:111/RISK_OWNER/2, new:111/RISK_OWNER/PRODUCT_TYPE
												ctrl.facility.limitNodePathList.push(facility.nodePath);
												ctrl.facility.facilityAttrList = angular.copy(ctrl.facility.facilityAttrs) ||[];
											}
										}
									});
									ctrl.facility.limitCcy = siteInfo.baseCcy;
									ctrl.facility.limitNodeIds.push($filter('encode')(facility.id));
									ctrl.facility.limitCatIds.push(facility.limitCatId);
									ctrl.facility.limitNodePaths = ctrl.facility.limitNodePathList.join('\n');
									//when parentNodeId is true, get parent attrs from facility.attrs, or facility.attr
									compareNodePath(ctrl, facility);
								}
							} else {
								ctrl.facility.limitCatIds.push(facility.limitCatId);
								ctrl.facility.limitNodeIds.push($filter('encode')(facility.id));
								ctrl.facility.limitNodePathList.push(facility.nodePath);
								ctrl.facility.limitNodePaths = ctrl.facility.limitNodePathList.join('\n');
								compareNodePath(ctrl, facility);
							}
						}
					}
				}
			};
		}
		
		function deleteWhenDoubleClick(ctrl, facility) {
			if ( facility.parentNodeId) {
				for ( var i=ctrl.facility.facilityAttrList.length-1;i>=0;i--){
					angular.forEach(facility.attrs, function(eachAttr, key){
						if ($filter('encode')(ctrl.facility.facilityAttrList[i].attrId) == $filter('encode')(eachAttr.attrId ) ) {
							if ( !ctrl.facility.facilityAttrList[i].mutiSeleted || ctrl.facility.facilityAttrList[i].mutiSeleted == 1) {
								ctrl.facility.facilityAttrList.splice(ctrl.facility.facilityAttrList.indexOf(ctrl.facility.facilityAttrList[i]), 1);
							} else {
								ctrl.facility.facilityAttrList[i].mutiSeleted --;
							}
						}
					});
				}
			} else {
				if (facility.attr != null ) {
					for ( var i=ctrl.facility.facilityAttrList.length-1;i>=0;i--){
						if ($filter('encode')(ctrl.facility.facilityAttrList[i].attrId) == $filter('encode')(facility.attr.attrId) ) {
							if ( !ctrl.facility.facilityAttrList[i].mutiSeleted || ctrl.facility.facilityAttrList[i].mutiSeleted == 1) {
								ctrl.facility.facilityAttrList.splice(ctrl.facility.facilityAttrList.indexOf(ctrl.facility.facilityAttrList[i]), 1);
							} else {
								ctrl.facility.facilityAttrList[i].mutiSeleted --;
							}
						}
					}
				}
			}
		}
		
		function compareNodePath( ctrl, facility ){
			var count = 0;
			if ( facility.parentNodeId) {														//(child) limitNode
				if (ctrl.facility.facilityAttrList!= null && ctrl.facility.facilityAttrList.length > 0) {
					angular.forEach( facility.attrs, function(eachAttr, key){
						var counts = 0;
						angular.forEach(ctrl.facility.facilityAttrList, function(attrValue, key) {
							if ($filter('encode')(attrValue.attrId) != $filter('encode')(eachAttr.attrId)) {
								counts ++;
//								attrValue.mutiSeleted = 1;
							} else {
								attrValue.mutiSeleted = attrValue.mutiSeleted == null ? 2 : ++attrValue.mutiSeleted;
							}
						});
						if ( counts == ctrl.facility.facilityAttrList.length) {
							eachAttr.mutiSeleted = 1;
							eachAttr.attrValueMode = eachAttr.attrValueMode == null ? 'N' : eachAttr.attrValueMode;
							ctrl.facility.facilityAttrList.push(eachAttr);
						}
					});
				} else {
					angular.forEach( facility.attrs, function(eachAttr, key){
						eachAttr.mutiSeleted = 1;
						eachAttr.attrValueMode = eachAttr.attrValueMode == null ? 'N' : eachAttr.attrValueMode;
						ctrl.facility.facilityAttrList.push(eachAttr);
					});
				}
			} else if (facility.attr != null && ctrl.facility.facilityAttrList!= null && ctrl.facility.facilityAttrList.length > 0 ){
				angular.forEach(ctrl.facility.facilityAttrList, function (attrValue, key) {		//(parent) limitNode
					if ( $filter('encode')(attrValue.attrId) != $filter('encode')(facility.attr.attrId)) {
						count ++;
//						attrValue.mutiSeleted = 1;
					} else {
						attrValue.mutiSeleted = attrValue.mutiSeleted == null ? 2 : ++attrValue.mutiSeleted;
					}
				});
				if ( count == ctrl.facility.facilityAttrList.length) {
					facility.attr.mutiSeleted = 1;
					facility.attr.attrValueMode = facility.attr.attrValueMode == null ? 'N' : facility.attr.attrValueMode;
					ctrl.facility.facilityAttrList.push(facility.attr);
				}
			} else {
				facility.attr.mutiSeleted = 1;
				facility.attr.attrValueMode = facility.attr.attrValueMode == null ? 'N' : facility.attr.attrValueMode;
				ctrl.facility.facilityAttrList.push(facility.attr);
			}
		}
		
		function initAttr( $scope, ctrl) {
			ctrl.layoutConfig.formConfigs.attributes.tableConfigs.table.validatorConfig = ctrl.validatorConfig.facilityAttrList;
			ctrl.innerGridOptions = gridService.createInnerGridOptions($scope, ctrl.layoutConfig.formConfigs.attributes.tableConfigs.table, rowSelectionChanged);
			ctrl.innerGridOptions.data = 'vm.facility.facilityAttrList';
			ctrl.innerGridOptions.enableRowHeaderSelection = false;
		}
		
		function rowSelectionChanged(eventRow, selectedRows) {
			ctrl.selectedDPParmList = selectedRows;
		}
		
		return {
			initOptionForSearch : initOptionForSearch,
			getCurrencyOptions : getCurrencyOptions,
			getDataStatus : getDataStatus,
			initTree : initTree,
			initAttr : initAttr,
			getLimitNodeIdList : getLimitNodeIdList
		};
	}
})(angular);
